package yc.tool.dbmigrate.dao.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import yc.tool.dbmigrate.common.Constant;
import yc.tool.dbmigrate.dao.AbstractCommonDao;
import yc.tool.dbmigrate.entity.FieldInfo;
import yc.tool.dbmigrate.entity.TableInfo;

import javax.annotation.Resource;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author sunjian
 * @createDate 2020/3/31 13:45
 */
@Repository("mysqlDao")
public class MysqlDaoImpl extends AbstractCommonDao {

    private static final Log log = LogFactory.get();

    @Resource(name="jdbcTemplate_mysql_source")
    private JdbcTemplate jdbcSource;
    @Resource(name="jdbcTemplate_mysql_tag")
    private JdbcTemplate jdbcTag;


    @Override
    public void init() {
        jdbcTemplate_source = jdbcSource;
        jdbcTemplate_tag = jdbcTag;
    }

    @Override
    public List<Map<String, Object>> selectOnePageData(TableInfo tableInfo, Integer pageNumber, Integer pageSize) throws Exception {
        // 不考虑where条件,因为我觉得同步完成后再去数据库进行手动删除更容易 亿点点
        StringBuilder sb = new StringBuilder();
        sb.append("select ");
        List<FieldInfo> fields = tableInfo.getFieldInfos();
        int size = fields.size();
        // 要同步的字段
        for (int i = 0; i < size; i++) {
            FieldInfo itemField = fields.get(i);
            sb.append(handleKeyWordInSql(itemField.getSourceFieldName()));
            if (i < size - 1) {
                sb.append(", ");
            }
        }
        // limit 1表示limit 0, 1
        // limit 1, 3表示从第2条数据开始,查询3条数据
        // 第1页: limit pagesize
        // 第2页: limit pagesize * 1, pagesize
        // 第3页: limit pagesize * 2, pagesize
        sb.append(" from ").append(tableInfo.getSourceTableName()).append(" limit ");
        sb.append((pageNumber - 1) * pageSize).append(", ").append(pageSize);
        log.info("oracle select sql: {}", sb);
        return jdbcSource.queryForList(sb.toString());
    }

    @Override
    public String handleKeyWordInSql(String fieldName) throws Exception {
        for (String item : Constant.KEYWORD_MYSQL) {
            if (item.equals(fieldName.toLowerCase())) {
                return "\""+fieldName.toUpperCase()+"\"";
            }
        }
        return fieldName;
    }

    @Override
    public void handleParamsForInsertFromSqlserver(PreparedStatement ps, Map<String, Object> itemData, TableInfo tableInfo) throws Exception {
        List<FieldInfo> fieldInfo = tableInfo.getFieldInfos();
        int size = fieldInfo.size();
        for (int i = 1; i <= size; i++) {
            FieldInfo itemFieldInfo = fieldInfo.get(i - 1);
            // mysql字段值
            Object itemTagFieldValue = itemData.get(itemFieldInfo.getSourceFieldName());
            // mysql字段类型
            String itemTagFieldType = itemFieldInfo.getTagFieldType().toLowerCase();
            ps.setObject(i, null);
            if (itemTagFieldValue != null) {
                // 根据字段类型插入数据
                if (itemTagFieldType.contains("int")) {
                    // 在mysql中,tinyint表示boolean,插入时可以插入0/1,也可以插入true/false
                    ps.setInt(i, Integer.parseInt(itemTagFieldValue.toString()));
                } else if (itemTagFieldType.contains("char") || itemTagFieldType.contains("text")) {
                    ps.setString(i, Convert.toStr(itemTagFieldValue, itemFieldInfo.getTagFieldNullable() ? null : " "));
                } else if (itemTagFieldType.contains("date") || itemTagFieldType.contains("time")) {
                    Date date = Convert.toDate(itemTagFieldValue);
                    ps.setTimestamp(i, date == null ? null : new Timestamp(date.getTime()));
                } else if (itemTagFieldType.contains("float") || itemTagFieldType.contains("double")
                        || itemTagFieldType.contains("decimal")) {
                    ps.setBigDecimal(i, Convert.toBigDecimal(itemTagFieldValue));
                }
            }
        }
    }

    @Override
    public void handleParamsForInsertFromOracle(PreparedStatement ps, Map<String, Object> itemData, TableInfo tableInfo) throws Exception {
        List<FieldInfo> fieldInfo = tableInfo.getFieldInfos();
        int size = fieldInfo.size();
        for (int i = 1; i <= size; i++) {
            FieldInfo itemFieldInfo = fieldInfo.get(i - 1);
            // mysql字段值
            Object itemTagFieldValue = itemData.get(itemFieldInfo.getSourceFieldName());
            // mysql字段类型
            String itemTagFieldType = itemFieldInfo.getTagFieldType().toLowerCase();
            ps.setObject(i, null);
            if (itemTagFieldValue != null) {
                // 根据字段类型插入数据
                if (itemTagFieldType.contains("int")) {
                    // 在mysql中,tinyint表示boolean,插入时可以插入0/1,也可以插入true/false
                    ps.setInt(i, Integer.parseInt(itemTagFieldValue.toString()));
                } else if (itemTagFieldType.contains("char") || itemTagFieldType.contains("text")) {
                    ps.setString(i, Convert.toStr(itemTagFieldValue, itemFieldInfo.getTagFieldNullable() ? null : " "));
                } else if (itemTagFieldType.contains("date") || itemTagFieldType.contains("time")) {
                    Date date = Convert.toDate(itemTagFieldValue);
                    ps.setTimestamp(i, date == null ? null : new Timestamp(date.getTime()));
                } else if (itemTagFieldType.contains("float") || itemTagFieldType.contains("double")
                        || itemTagFieldType.contains("decimal")) {
                    ps.setBigDecimal(i, Convert.toBigDecimal(itemTagFieldValue));
                }
            }
        }
    }

    @Override
    public void handleParamsForInsertFromMysql(PreparedStatement ps, Map<String, Object> itemData, TableInfo tableInfo) throws Exception {
        // 同为mysql意义不大
    }
}
